package jnpf.engine.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import groovy.lang.GroovyShell;
import jnpf.base.UserInfo;
import jnpf.base.entity.DictionaryDataEntity;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.base.service.DictionaryDataService;
import jnpf.base.service.SuperServiceImpl;
import jnpf.constant.PermissionConst;
import jnpf.engine.custom.constants.BasicActivitiConstants;
import jnpf.engine.entity.*;
import jnpf.engine.enums.FlowNodeTypeEnum;
import jnpf.engine.enums.FlowScriptTypeEnum;
import jnpf.engine.enums.FlowTaskOperatorEnum;
import jnpf.engine.enums.FlowTemplateRelationTypEnum;
import jnpf.engine.mapper.FlowTemplateMapper;
import jnpf.engine.model.flowengine.FlowPagination;
import jnpf.engine.model.flowengine.shuntjson.childnode.ChildNode;
import jnpf.engine.model.flowengine.shuntjson.childnode.MsgConfig;
import jnpf.engine.model.flowengine.shuntjson.childnode.ProperCond;
import jnpf.engine.model.flowengine.shuntjson.childnode.Properties;
import jnpf.engine.model.flowengine.shuntjson.nodejson.ChildNodeList;
import jnpf.engine.model.flowengine.shuntjson.nodejson.ConditionList;
import jnpf.engine.model.flowengine.shuntjson.nodejson.Custom;
import jnpf.engine.model.flowtemplate.FlowExportModel;
import jnpf.engine.model.flowtemplate.FlowTemplateInfoVO;
import jnpf.engine.model.flowtemplate.FlowTemplateListVO;
import jnpf.engine.model.flowtemplate.FlowTemplateVO;
import jnpf.engine.model.flowtemplatejson.FlowJsonModel;
import jnpf.engine.model.flowtemplatejson.FlowTemplateJsonPage;
import jnpf.engine.service.*;
import jnpf.engine.util.BpmnModelUtils;
import jnpf.engine.util.EvalUtils;
import jnpf.engine.util.FlowJsonUtil;
import jnpf.engine.util.JsonZipUtil;
import jnpf.entity.FlowFormEntity;
import jnpf.exception.WorkFlowException;
import jnpf.permission.entity.UserEntity;
import jnpf.service.FlowFormService;
import jnpf.service.TemplateRelationService;
import jnpf.util.*;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.groovy.control.MultipleCompilationErrorsException;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.impl.persistence.entity.DeploymentEntityImpl;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
import org.flowable.engine.repository.Deployment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static jnpf.engine.custom.constants.BasicActivitiConstants.SEQUENCE_FLOW_WITH_CONDITION_EXPRESSION;
import static jnpf.engine.custom.constants.BasicActivitiConstants.activitiPrefix;
import static org.flowable.engine.impl.bpmn.behavior.CallActivityBehavior.CALLED_ELEMENT_TYPE_KEY;


/**
 * 流程引擎
 *
 * @author JNPF开发平台组
 * @version V3.4.2
 * @copyright 引迈信息技术有限公司
 * @date 2022年7月11日 上午9:18
 */
@Service
public class FlowTemplateServiceImpl extends SuperServiceImpl<FlowTemplateMapper, FlowTemplateEntity> implements FlowTemplateService {

    @Autowired
    @Lazy
    private FlowTaskService flowTaskService;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private ServiceAllUtil serviceUtil;
    @Autowired
    private FlowEngineVisibleService flowEngineVisibleService;
    @Autowired
    private FlowTemplateJsonService flowTemplateJsonService;
    @javax.annotation.Resource
    private RepositoryService repositoryService;
    @javax.annotation.Resource
    private FlowFormService flowFormService;
    @javax.annotation.Resource
    private RuntimeService runtimeService;
    @Resource
    private HistoryService historyService;
    @Value("${spring.profiles.active:}")
    private String activtes;
    @Resource
    private FlowDefinitionService flowDefinitionService;
    @Resource
    private DictionaryDataService dictionaryDataService;
    @Resource
    private TemplateRelationService templateRelationService;

    @Override
    public List<FlowTemplateListVO> getTreeList() {
        FlowPagination pagination = new FlowPagination();
        List<FlowTemplateEntity> data = getListAll(pagination, false);
        List<DictionaryDataEntity> dictionList = serviceUtil.getDiList();
        Map<Integer, List<FlowTemplateEntity>> typeList = data.stream().collect(Collectors.groupingBy(FlowTemplateEntity::getType));
        List<FlowTemplateListVO> listVOS = new LinkedList<>();
        for (Integer key : typeList.keySet()) {
            boolean type = Objects.equals(0, key);
            //发起类型
            FlowTemplateListVO model = new FlowTemplateListVO();
            model.setId(key + "");
            model.setFullName(type ? "发起流程" : "功能流程");
            model.setDisabled(true);
            Map<String, List<FlowTemplateEntity>> dataList = typeList.get(key).stream().collect(Collectors.groupingBy(FlowTemplateEntity::getCategory));
            List<FlowTemplateListVO> dictionListVOS = new LinkedList<>();
            for (DictionaryDataEntity entity : dictionList) {
                FlowTemplateListVO dictionModel = new FlowTemplateListVO();
                dictionModel.setFullName(entity.getFullName());
                dictionModel.setId(RandomUtil.uuId());
                List<FlowTemplateEntity> childList = dataList.get(entity.getId()) != null ? dataList.get(entity.getId()) : new ArrayList<>();
                dictionModel.setDisabled(true);
                if (childList.size() > 0) {
                    dictionModel.setChildren(JsonUtil.getJsonToList(childList, FlowTemplateListVO.class));
                    dictionModel.setNum(childList.size());
                    dictionListVOS.add(dictionModel);
                }
            }
            if (dictionListVOS.size() > 0) {
                model.setChildren(dictionListVOS);
                listVOS.add(model);
            }
        }
        return listVOS;
    }

    @Override
    public List<FlowTemplateListVO> getSelectList() {
        FlowPagination pagination = new FlowPagination();
        pagination.setFlowType(0);
        List<FlowTemplateEntity> data = getListAll(pagination, false);
        List<DictionaryDataEntity> dictionList = serviceUtil.getDiList();
        Map<String, List<FlowTemplateEntity>> dataList = data.stream().collect(Collectors.groupingBy(FlowTemplateEntity::getCategory));
        List<FlowTemplateListVO> listVOS = new LinkedList<>();
        for (DictionaryDataEntity entity : dictionList) {
            FlowTemplateListVO model = new FlowTemplateListVO();
            model.setFullName(entity.getFullName());
            model.setId(entity.getId());
            List<FlowTemplateEntity> childList = dataList.get(entity.getId()) != null ? dataList.get(entity.getId()) : new ArrayList<>();
            model.setNum(childList.size());
            if (childList.size() > 0) {
                model.setChildren(JsonUtil.getJsonToList(childList, FlowTemplateListVO.class));
            }
            listVOS.add(model);
        }
        return listVOS;
    }
    @Override
    public List<FlowTemplateEntity> getPageList(FlowPagination pagination) {
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;

        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(pagination.getOrgId())) {
            List<String> objectIds = templateRelationService.getObjectIdsByOrganizeId(FlowTemplateRelationTypEnum.DEPT, pagination.getOrgId());
            if (CollectionUtil.isNotEmpty(objectIds)) {
                queryWrapper.lambda().in(SuperBaseEntity.SuperIBaseEntity::getId, objectIds);
            }
        }
        if (ObjectUtil.isNotEmpty(pagination.getKeyword())) {
            flag = true;
            queryWrapper.lambda().and(
                    t -> t.like(FlowTemplateEntity::getFullName, pagination.getKeyword())
                            .or().like(FlowTemplateEntity::getEnCode, pagination.getKeyword())
            );
        }
        if (ObjectUtil.isNotEmpty(pagination.getCategory())) {
            flag = true;
            DictionaryDataEntity infoByEnCode = dictionaryDataService.getInfoByEnCode(pagination.getCategory());
            if (Objects.nonNull(infoByEnCode)) {
                queryWrapper.lambda().eq(FlowTemplateEntity::getCategory, infoByEnCode.getId());
            }

        }
        if (ObjectUtil.isNotEmpty(pagination.getType())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTemplateEntity::getType, pagination.getType());
        }
        if (ObjectUtil.isNotEmpty(pagination.getEnabledMark())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTemplateEntity::getEnabledMark, pagination.getEnabledMark());
        }
        //排序
        queryWrapper.lambda().orderByAsc(FlowTemplateEntity::getSortCode).orderByDesc(FlowTemplateEntity::getCreatorTime);
        if (flag) {
            queryWrapper.lambda().orderByDesc(FlowTemplateEntity::getLastModifyTime);
        }
        if (StringUtil.isNotEmpty(pagination.getOrgId())) {
            queryWrapper.lambda().like(FlowTemplateEntity::getOrgId, pagination.getOrgId());
        }
        Page<FlowTemplateEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<FlowTemplateEntity> userPage = this.page(page, queryWrapper);
        return pagination.setData(userPage.getRecords(), page.getTotal());
    }


    @Override
    public FlowTemplateEntity getInfo(String id) throws WorkFlowException {
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getId, id);
        FlowTemplateEntity FlowTemplateEntity = this.getOne(queryWrapper);
        if (FlowTemplateEntity == null) {
            throw new WorkFlowException("未找到流程引擎");
        }
        return FlowTemplateEntity;
    }

    @Override
    public boolean isExistByFullName(String fullName, String id) {
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getFullName, fullName);
        queryWrapper.lambda().eq(FlowTemplateEntity::getType, 0);
        if (!ObjectUtil.isEmpty(id)) {
            queryWrapper.lambda().ne(FlowTemplateEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public boolean isExistByEnCode(String enCode, String id) {
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getEnCode, enCode);
        if (!ObjectUtil.isEmpty(id)) {
            queryWrapper.lambda().ne(FlowTemplateEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    @DSTransactional
    public void create(FlowTemplateEntity entity, List<FlowTemplateJsonEntity> templateJsonList) throws WorkFlowException {
        if (isExistByFullName(entity.getFullName(), entity.getId())) {
            throw new WorkFlowException("流程名称不能重复");
        }
        if (isExistByEnCode(entity.getEnCode(), entity.getId())) {
            throw new WorkFlowException("流程编码不能重复");
        }
        boolean formType = entity.getType() == 1;
        UserInfo userInfo = userProvider.get();
        entity.setId(StringUtil.isNotEmpty(entity.getId()) ? entity.getId() : RandomUtil.uuId());
        entity.setCreatorUserId(userInfo.getUserId());
        entity.setCreatorTime(new Date());
        entity.setEnabledMark(0);
        entity.setLastModifyUserId(null);
        entity.setLastModifyTime(null);
        this.setIgnoreLogicDelete().removeById(entity.getId());
        this.setIgnoreLogicDelete().saveOrUpdate(entity);
        this.clearIgnoreLogicDelete();
        // 保存关联组织机构关系
        ArrayList<String> organizeIdList = Lists.newArrayList(entity.getOrgId().split(","));
        templateRelationService.updateRelation(FlowTemplateRelationTypEnum.DEPT, organizeIdList, entity.getId());
        List<String> tempIdList = ImmutableList.of(entity.getId());
        List<FlowTemplateJsonEntity> templateList = flowTemplateJsonService.getTemplateList(tempIdList);
        Set<String> formIdList = new HashSet<>();
        //保存引擎数据
        for (int k = 0; k < templateJsonList.size(); k++) {
            FlowTemplateJsonEntity templateJson = templateJsonList.get(k);
            templateJson.setId(StringUtil.isNotEmpty(templateJson.getId()) ? templateJson.getId() : RandomUtil.uuId());
            templateJson.setTemplateId(entity.getId());
            templateJson.setGroupId(StringUtil.isNotEmpty(templateJson.getGroupId()) ? templateJson.getGroupId() : RandomUtil.uuId());
            //解析和构建bpmn
            List<FlowEngineVisibleEntity> visibleList = visibleList(templateJson, formType, formIdList,entity);
            flowEngineVisibleService.deleteVisible(templateJson.getId());
            int version = templateList.stream().filter(t -> t.getGroupId().equals(templateJson.getGroupId())).map(FlowTemplateJsonEntity::getVersion).mapToInt(Integer::parseInt).max().orElse(0) + 1;
            templateJson.setVersion(version + "");
            templateJson.setSortCode(Long.parseLong(k + ""));
            templateJson.setVisibleType(visibleList.size() == 0 ? 0 : 1);
            templateJson.setEnabledMark(1);
            flowTemplateJsonService.setIgnoreLogicDelete().removeById(templateJson.getId());
            flowTemplateJsonService.setIgnoreLogicDelete().saveOrUpdate(templateJson);
            flowTemplateJsonService.clearIgnoreLogicDelete();
            for (int i = 0; i < visibleList.size(); i++) {
                FlowEngineVisibleEntity visibleEntity = visibleList.get(i);
                visibleEntity.setId(RandomUtil.uuId());
                visibleEntity.setFlowId(templateJson.getId());
                visibleEntity.setSortCode(Long.parseLong(i + ""));
                flowEngineVisibleService.save(visibleEntity);
            }
        }
        if (formType && formIdList.size() > 1) {
            throw new WorkFlowException("流程表单不一致，请重新选择。");
        }
        serviceUtil.formIdList(new ArrayList<>(formIdList), entity.getId());
    }

    @Override
    public void create(FlowTemplateEntity entity) {
        UserInfo userInfo = userProvider.get();
        entity.setId(StringUtil.isNotEmpty(entity.getId()) ? entity.getId() : RandomUtil.uuId());
        entity.setCreatorUserId(userInfo.getUserId());
        entity.setCreatorTime(new Date());
        entity.setEnabledMark(0);
        this.saveOrUpdate(entity);
    }

    @Override
    public FlowTemplateInfoVO info(String id) throws WorkFlowException {
        FlowTemplateEntity flowEntity = getInfo(id);
        FlowTemplateInfoVO vo = JsonUtil.getJsonToBean(flowEntity, FlowTemplateInfoVO.class);
        FlowTemplateJsonPage page = new FlowTemplateJsonPage();
        page.setTemplateId(id);
        List<FlowTemplateJsonEntity> listAll = flowTemplateJsonService.getListPage(page, false);
        List<FlowTemplateJsonEntity> list = flowTemplateJsonService.getMainList(ImmutableList.of(id));
        List<FlowTaskEntity> flowTaskList = flowTaskService.getTemplateIdList(id);
        List<FlowJsonModel> templateList = new ArrayList<>();
        for (FlowTemplateJsonEntity templateJson : list) {
            FlowJsonModel model = new FlowJsonModel();
            model.setFlowId(templateJson.getId());
            model.setId(templateJson.getId());
            model.setFullName(templateJson.getFullName());
            model.setFlowTemplateJson(JsonUtil.stringToMap(templateJson.getFlowTemplateJson()));
            List<String> flowIdList = listAll.stream().filter(t -> templateJson.getGroupId().equals(t.getGroupId())).map(FlowTemplateJsonEntity::getId).collect(Collectors.toList());
            boolean isDelete = flowTaskList.stream().filter(t -> flowIdList.contains(t.getFlowId())).count() > 0;
            model.setIsDelete(isDelete);
            templateList.add(model);
        }
        //判断是否是在线开发同步过来的流程
        List<FlowFormEntity> formList = serviceUtil.getFlowIdList(id);
        String onlineFormId = "";
        if (formList.size() > 0) {
            FlowFormEntity form = formList.get(0);
            if (form != null && form.getFlowType() == 1 && form.getFormType() == 2) {
                onlineFormId = form.getId();
            }
        }
        vo.setOnlineDev(StringUtil.isNotEmpty(onlineFormId));
        vo.setOnlineFormId(onlineFormId);
        vo.setFlowTemplateJson(JsonUtil.getObjectToString(templateList));
        return vo;
    }

    @Override
    @DSTransactional
    public FlowTemplateVO updateVisible(String id, FlowTemplateEntity entity, List<FlowTemplateJsonEntity> templateJsonList) throws WorkFlowException {
        if (isExistByFullName(entity.getFullName(), id)) {
            throw new WorkFlowException("流程名称不能重复");
        }
        if (isExistByEnCode(entity.getEnCode(), id)) {
            throw new WorkFlowException("流程编码不能重复");
        }
        boolean formType = entity.getType() == 1;
        UserInfo userInfo = userProvider.get();
        FlowTemplateVO vo = new FlowTemplateVO();
        List<String> listVO = new ArrayList<>();
        entity.setId(id);
        entity.setLastModifyTime(new Date());
        entity.setLastModifyUserId(userInfo.getUserId());
        this.saveOrUpdate(entity);
        if (StringUtil.isNotEmpty(entity.getOrgId())) {
            // 更新关联组织机构关系
            ArrayList<String> organizeIdList = Lists.newArrayList(entity.getOrgId().split(","));
            templateRelationService.updateRelation(FlowTemplateRelationTypEnum.DEPT, organizeIdList, entity.getId());

        }
        //删除没有用到的流程
        List<FlowTemplateJsonEntity> templateList = flowTemplateJsonService.getMainList(ImmutableList.of(entity.getId()));
        for (int i = 0; i < templateList.size(); i++) {
            FlowTemplateJsonEntity templateJson = templateList.get(i);
            List<FlowTaskEntity> flowList = flowTaskService.getFlowList(templateJson.getId());
            if (flowList.size() > 0) {
                templateList.remove(i);
            }
        }
        List<String> tempJsonIdList = templateList.stream().map(FlowTemplateJsonEntity::getId).collect(Collectors.toList());
        List<String> templateJsonId = templateJsonList.stream().filter(t -> StringUtil.isNotEmpty(t.getId())).map(FlowTemplateJsonEntity::getId).collect(Collectors.toList());
        tempJsonIdList.removeAll(templateJsonId);
        for (String tempJsonId : tempJsonIdList) {
            FlowTemplateJsonEntity delTemplateJson = flowTemplateJsonService.getInfo(tempJsonId);
            flowEngineVisibleService.deleteVisible(delTemplateJson.getId());
            flowTemplateJsonService.delete(delTemplateJson);
        }
        Set<String> formIdList = new HashSet<>();
        //保存引擎数据
        for (int k = 0; k < templateJsonList.size(); k++) {
            FlowTemplateJsonEntity templateJson = templateJsonList.get(k);
            templateJson.setSecondKey(entity.getEnCode()+ cn.hutool.core.util.RandomUtil.randomNumbers(6));
            boolean isTempId = StringUtil.isNotEmpty(templateJson.getId());
            String jsonId = isTempId ? templateJson.getId() : RandomUtil.uuId();
            //json变化才新增版本，true=变化
            FlowTemplateJsonEntity info = isTempId ? flowTemplateJsonService.getInfo(jsonId) : null;
            boolean isRand = true;
            //这里永为true,不管与之前json对比如何都新建版本
            templateJson.setId(isRand ? RandomUtil.uuId() : jsonId);
            templateJson.setTemplateId(id);
            //分组用之前的
            templateJson.setGroupId(isTempId ? info.getGroupId() : RandomUtil.uuId());
            int version = 1;
            //判断是否在使用,新增版本
            if (isRand) {
                version = flowTemplateJsonService.getTemplateList(ImmutableList.of(id)).stream().filter(t -> t.getGroupId().equals(templateJson.getGroupId())).map(FlowTemplateJsonEntity::getVersion).mapToInt(Integer::parseInt).max().orElse(0) + 1;
                listVO.add(templateJson.getId());
            }
            List<FlowEngineVisibleEntity> visibleList = visibleList(templateJson, formType, formIdList,entity);
            flowEngineVisibleService.deleteVisible(templateJson.getId());
            templateJson.setVisibleType(visibleList.size() == 0 ? 0 : 1);
            templateJson.setSortCode(Long.parseLong(k + ""));
            templateJson.setEnabledMark(isRand ? 0 : isTempId ? info.getEnabledMark() : 1);
            templateJson.setVersion(isRand ? version + "" : isTempId ? info.getVersion() : version + "");
            flowTemplateJsonService.saveOrUpdate(templateJson);
            for (int i = 0; i < visibleList.size(); i++) {
                FlowEngineVisibleEntity visibleEntity = visibleList.get(i);
                visibleEntity.setId(RandomUtil.uuId());
                visibleEntity.setFlowId(templateJson.getId());
                visibleEntity.setSortCode(Long.parseLong(i + ""));
                flowEngineVisibleService.save(visibleEntity);
            }
            flowTemplateJsonService.updateFullName(templateJson.getGroupId(), templateJson.getFullName());
        }
        vo.setIsMainVersion(listVO.size() > 0);
        vo.setId(String.join(",", listVO));
        if (formType && formIdList.size() > 1) {
            throw new WorkFlowException("流程表单不一致，请重新选择。");
        }
        serviceUtil.formIdList(new ArrayList<>(formIdList), entity.getId());
        return vo;
    }

    @Override
    public boolean update(String id, FlowTemplateEntity entity) {
        entity.setId(id);
        boolean flag = this.updateById(entity);
        return flag;
    }

    @Override
    @DSTransactional
    public void copy(FlowTemplateEntity entity, List<FlowTemplateJsonEntity> templateJsonEntity) throws WorkFlowException {
        try {
            String copyNum = UUID.randomUUID().toString().substring(0, 5);
            entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            entity.setEnCode(entity.getEnCode() + copyNum);
            entity.setId(null);
            entity.setLastModifyTime(null);
            entity.setLastModifyUserId(null);
            for (FlowTemplateJsonEntity jsonEntity : templateJsonEntity) {
                jsonEntity.setCreatorUserId(userProvider.get().getUserId());
                jsonEntity.setCreatorTime(new Date());
                jsonEntity.setLastModifyUserId(null);
                jsonEntity.setLastModifyTime(null);
                jsonEntity.setGroupId(null);
                jsonEntity.setId(null);
            }
            this.create(entity, templateJsonEntity);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new WorkFlowException("异常");
        }
    }

    @Override
    @DSTransactional
    public void delete(FlowTemplateEntity entity) throws WorkFlowException {
        FlowFormEntity form = serviceUtil.getForm(entity.getId());
        if (form != null && form.getFlowType() == 1 && form.getFormType() == 2) {
            throw new WorkFlowException("该流程由在线开发生成的，无法直接删除，请在功能设计中删除相关功能！");
        }
        List<FlowTaskEntity> flowTaskList = flowTaskService.getTemplateIdList(entity.getId());
        if (flowTaskList.size() > 0) {
            throw new WorkFlowException("该流程内工单任务流转未结束，无法删除！");
        }
        List<FlowTemplateJsonEntity> list = flowTemplateJsonService.getTemplateList(ImmutableList.of(entity.getId()));
        // 删除组织结构关系
        templateRelationService.deleteByObjectId(FlowTemplateRelationTypEnum.DEPT, entity.getId());
        // 删除流程模板
        this.removeById(entity.getId());
        serviceUtil.formIdList(new ArrayList<>(), entity.getId());
        for (FlowTemplateJsonEntity templateJson : list) {
            List<String> sendConfigIdList = flowTemplateJsonService.sendMsgConfigList(templateJson);
            if (sendConfigIdList != null && sendConfigIdList.size() > 0) {
                serviceUtil.updateSendConfigUsed(entity.getId(), sendConfigIdList);
            }
            serviceUtil.deleteFormId(templateJson.getId());
            flowEngineVisibleService.deleteVisible(templateJson.getId());
            flowTemplateJsonService.deleteFormFlowId(templateJson);
            String processDefinitionId = templateJson.getProcessDefinitionId();
            if(StringUtils.isNotBlank(processDefinitionId)){
                long count = historyService.createHistoricProcessInstanceQuery().processDefinitionId(processDefinitionId).count();
                if(count>0){
                    throw new WorkFlowException("该流程内工单任务流转未结束，无法删除！");
                }
                repositoryService.deleteDeployment(templateJson.getDeploymentId(),true);
            }
        }
    }

    @Override
    public FlowExportModel exportData(String id) throws WorkFlowException {
        FlowTemplateEntity entity = getInfo(id);
        List<FlowTemplateJsonEntity> templateJsonList = flowTemplateJsonService.getMainList(ImmutableList.of(id));
        FlowExportModel model = new FlowExportModel();
        model.setFlowTemplate(entity);
        model.setFlowTemplateJson(templateJsonList);
        return model;
    }

    @Override
    @DSTransactional
    public void ImportData(FlowExportModel flowExportModel, String type) throws WorkFlowException {
        FlowTemplateEntity entity = flowExportModel.getFlowTemplate();
        List<FlowTemplateJsonEntity> flowTemplateJson = flowExportModel.getFlowTemplateJson();
        if (entity != null) {
            StringJoiner joiner = new StringJoiner("；");
            entity.setCreatorUserId(UserProvider.getLoginUserId());
            entity.setCreatorTime(new Date());
            entity.setLastModifyTime(null);
            entity.setLastModifyUserId(null);
            entity.setEnabledMark(0);
            List<String> templateList = new ArrayList<>();
            FlowTemplateEntity templateEntity = Import(entity, type, templateList);
            if (templateList.size() > 0) {
                joiner.add(String.join("、", templateList) + "重复");
            }
            List<FlowTemplateJsonEntity> jsonList = new ArrayList<>();
            if (ObjectUtil.isNotEmpty(flowTemplateJson)) {
                List<String> idList = new ArrayList<>();
                List<String> nameList = new ArrayList<>();
                StringJoiner childJoiner = new StringJoiner("、");
                for (FlowTemplateJsonEntity templateJsonEntity : flowTemplateJson) {
                    templateJsonEntity.setCreatorUserId(UserProvider.getLoginUserId());
                    templateJsonEntity.setCreatorTime(new Date());
                    templateJsonEntity.setLastModifyTime(null);
                    templateJsonEntity.setLastModifyUserId(null);
                    templateJsonEntity.setGroupId(null);
                    FlowTemplateJsonEntity jsonEntity = Import(templateJsonEntity, type, idList, nameList);
                    jsonList.add(jsonEntity);
                }
                if (idList.size() > 0) {
                    childJoiner.add("ID(" + String.join("、", idList) + ")");
                }
                if (nameList.size() > 0) {
                    childJoiner.add("名称(" + String.join("、", nameList) + ")");
                }
                if (childJoiner.length() > 0) {
                    joiner.add("flowTemplateJson：" + childJoiner + "重复");
                }
            }
            if (StringUtil.isNotEmpty(joiner.toString())) {
                throw new WorkFlowException(joiner.toString());
            }
            create(templateEntity, jsonList);
        }
    }




    @Override
    public List<FlowTemplateEntity> getTemplateList(List<String> id) {
        List<FlowTemplateEntity> list = new ArrayList<>();
        if (id.size() > 0) {
            QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(FlowTemplateEntity::getId, id);
            list = this.list(queryWrapper);
        }
        return list;
    }

    @Override
    public FlowTemplateEntity getFlowIdByCode(String code) throws WorkFlowException {
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getEnCode, code);
        FlowTemplateEntity FlowTemplateEntity = this.getOne(queryWrapper);
        if (FlowTemplateEntity == null) {
            throw new WorkFlowException("异常");
        }
        return FlowTemplateEntity;
    }

    @Override
    public List<FlowTemplateEntity> getListAll(FlowPagination pagination, boolean isPage) {
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;
        UserInfo userInfo = userProvider.get();
        // 如果参数传递了userId则覆盖
        if (StringUtil.isNotEmpty(pagination.getUserId())) {
            userInfo.setId(pagination.getUserId());
        }
        boolean visibleType = userInfo.getIsAdministrator();
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        if (!isPage || !visibleType) {
            List<String> id = flowEngineVisibleService.getVisibleFlowList(userInfo.getUserId()).stream().map(FlowEngineVisibleEntity::getFlowId).collect(Collectors.toList());
            List<String> listAll = flowTemplateJsonService.getListAll(id).stream().map(FlowTemplateJsonEntity::getTemplateId).collect(Collectors.toList());
            if (listAll.size() == 0) {
                return new ArrayList<>();
            }
            queryWrapper.lambda().in(FlowTemplateEntity::getId, listAll);
        }
        queryWrapper.lambda().eq(FlowTemplateEntity::getEnabledMark, 1);
        if (ObjectUtil.isNotEmpty(pagination.getFlowType())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTemplateEntity::getType, pagination.getFlowType());
        }
        if (ObjectUtil.isNotEmpty(pagination.getKeyword())) {
            flag = true;
            queryWrapper.lambda().like(FlowTemplateEntity::getFullName, pagination.getKeyword());
        }
        if (ObjectUtil.isNotEmpty(pagination.getCategory())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTemplateEntity::getCategory, pagination.getCategory());
        }
        if (ObjectUtil.isNotEmpty(pagination.getTemplateIdList())) {
            queryWrapper.lambda().in(FlowTemplateEntity::getId, pagination.getTemplateIdList());
        }
        queryWrapper.lambda().orderByAsc(FlowTemplateEntity::getSortCode).orderByDesc(FlowTemplateEntity::getCreatorTime);
        if (flag) {
            queryWrapper.lambda().orderByDesc(FlowTemplateEntity::getLastModifyTime);
        }
        queryWrapper.lambda().select(
                FlowTemplateEntity::getId, FlowTemplateEntity::getEnCode,
                FlowTemplateEntity::getFullName,
                FlowTemplateEntity::getType, FlowTemplateEntity::getIcon,
                FlowTemplateEntity::getCategory, FlowTemplateEntity::getIconBackground,
                FlowTemplateEntity::getCreatorUserId, FlowTemplateEntity::getSortCode,
                FlowTemplateEntity::getEnabledMark, FlowTemplateEntity::getCreatorTime
        );
        if (isPage) {
            Page<FlowTemplateEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
            IPage<FlowTemplateEntity> userPage = this.page(page, queryWrapper);
            return pagination.setData(userPage.getRecords(), page.getTotal());
        } else {
            return this.list(queryWrapper);
        }
    }


    private List<FlowEngineVisibleEntity> visibleList(FlowTemplateJsonEntity entity, boolean formType, Set<String> formIdList,FlowTemplateEntity flowTemplateEntity) throws WorkFlowException {
        List<FlowEngineVisibleEntity> visibleList = new ArrayList<>();
        //流程模板id
        String templeId = entity.getTemplateId();
        //流程模板json数据
        String flowTemplate = StringUtil.isNotEmpty(entity.getFlowTemplateJson()) ? entity.getFlowTemplateJson() : "{}";
        //流程模板数据转为流程节点
        ChildNode childNode = JsonUtil.getJsonToBean(flowTemplate, ChildNode.class);
        //获取开始节点配置
        Properties properties = childNode.getProperties();
        //判断节点是否含有表单
        if (formType) {
            //获取节点配置表单
            FlowFormEntity form = serviceUtil.getForm(properties.getFormId());
            /*if (form != null && StringUtil.isNotEmpty(form.getFlowId()) && !form.getFlowId().equals(templeId)) {
                throw new WorkFlowException("表单已被引用，请重新选择！");
            }*/
            //清空 原先绑定的功能表单流程id
            List<FlowFormEntity> flowIdList = serviceUtil.getFlowIdList(templeId);
            for (FlowFormEntity formEntity : flowIdList) {
                //逗号隔开的多个flowId处理
                List<String> flowIds = Lists.newArrayList(formEntity.getFlowId().split(","));
                flowIds.remove(templeId);
                formEntity.setFlowId(CollectionUtil.isEmpty(flowIds)?null:String.join(",",flowIds));
                serviceUtil.updateForm(formEntity);
            }
            if (form != null) {
                //多flowIds处理
                List<String> flowIds = StringUtil.isNotEmpty(form.getFlowId()) ? Lists.newArrayList(form.getFlowId().split(",")) : new ArrayList<>();
                flowIds.add(templeId);
                form.setFlowId(String.join(",",flowIds));
                serviceUtil.updateForm(form);
            }
        }
        if (StringUtil.isNotEmpty(properties.getFormId())) {
            formIdList.add(properties.getFormId());
        }

        //是否批量审批
        Boolean isBatchApproval = childNode.getProperties().getIsBatchApproval();
        BpmnModel bpmnModel= new BpmnModel();
        //解析设置bpmn基础配置信息
        BpmnModelUtils.setBpmnModelInfo(bpmnModel,flowTemplateEntity);
        //创建流程定义 在bpmn中写入基础配置数据
        Process process = BpmnModelUtils.createProcess(entity, flowTemplateEntity);
        bpmnModel.addProcess(process);
        //解析流程模板节点 填充bpmn流程节点信息
        bpmnModel = assemBpmnModel(childNode,bpmnModel,process);
        //调用流程引擎 流程部署
        Deployment deployment = repositoryService.createDeployment()
                .addBpmnModel(entity.getFullName() + jnpf.engine.custom.constants.BasicActivitiConstants.bpmnSuffix, bpmnModel)
                .name(entity.getFullName())
                .category(flowTemplateEntity.getCategory())
                .tenantId(userProvider.get().getTenantId())
                .deploy();
        //获取流程定义id
        String processDefinitionId=((DeploymentEntityImpl) deployment).getDeployedArtifacts(ProcessDefinitionEntityImpl.class).get(0).getId();
        //回填信息
        entity.setProcessDefinitionId(processDefinitionId);
        entity.setDeploymentId(deployment.getId());
        entity.setBatch(isBatchApproval?1:2);
        entity.setTemplateName(flowTemplateEntity.getFullName());
//        entity.setFlowTemplateJson(JsonUtilEx.getObjectToString(childNode));
        //流程可见
        for (String initiator : properties.getInitiator()) {
            String type = initiator.split("--").length > 1 ? initiator.split("--")[1] : PermissionConst.USER;
            String operatorId = initiator.split("--")[0];
            FlowEngineVisibleEntity visible = new FlowEngineVisibleEntity();
            visible.setOperatorId(operatorId);
            visible.setOperatorType(type);
            visible.setType(1);
            visibleList.add(visible);
        }
        List<ChildNodeList> nodeListAll = new ArrayList<>();
        List<ConditionList> conditionListAll = new ArrayList<>();
        //获取所有节点和条件信息
        FlowJsonUtil.getTemplateAll(childNode, nodeListAll, conditionListAll);
        List<String> sendIdList = new ArrayList<>();
        List<FlowDefinitiontEntity> flowDefinitiontEntities = new ArrayList<>();
       Set<String> formIdSet = new HashSet<>();
        for (ChildNodeList childNodeList : nodeListAll) {
            //获取节点配置信息
            Properties childProperties = childNodeList.getProperties();
            //代办信息
            MsgConfig waitMsgConfig = childProperties.getWaitMsgConfig();
            if (StringUtil.isNotEmpty(waitMsgConfig.getMsgId())) {
                sendIdList.add(waitMsgConfig.getMsgId());
            }
            //结束信息
            MsgConfig endMsgConfig = childProperties.getEndMsgConfig();
            if (StringUtil.isNotEmpty(endMsgConfig.getMsgId())) {
                sendIdList.add(endMsgConfig.getMsgId());
            }
            //通过信息
            MsgConfig approveMsgConfig = childProperties.getApproveMsgConfig();
            if (StringUtil.isNotEmpty(approveMsgConfig.getMsgId())) {
                sendIdList.add(approveMsgConfig.getMsgId());
            }
            //驳回信息
            MsgConfig rejectMsgConfig = childProperties.getRejectMsgConfig();
            if (StringUtil.isNotEmpty(rejectMsgConfig.getMsgId())) {
                sendIdList.add(rejectMsgConfig.getMsgId());
            }
            //抄送信息
            MsgConfig copyMsgConfig = childProperties.getCopyMsgConfig();
            if (StringUtil.isNotEmpty(copyMsgConfig.getMsgId())) {
                sendIdList.add(copyMsgConfig.getMsgId());
            }
            //子流程信息
            MsgConfig launchMsgConfig = childProperties.getLaunchMsgConfig();
            if (StringUtil.isNotEmpty(launchMsgConfig.getMsgId())) {
                sendIdList.add(launchMsgConfig.getMsgId());
            }
            //超时信息
            MsgConfig overtimeMsgConfig = childProperties.getOvertimeMsgConfig();
            if (StringUtil.isNotEmpty(overtimeMsgConfig.getMsgId())) {
                sendIdList.add(overtimeMsgConfig.getMsgId());
            }
            //提醒信息
            MsgConfig noticeMsgConfig = childProperties.getNoticeMsgConfig();
            if (StringUtil.isNotEmpty(noticeMsgConfig.getMsgId())) {
                sendIdList.add(noticeMsgConfig.getMsgId());
            }
            if(StringUtil.isNotEmpty(childProperties.getFormId())){
                formIdSet.add(childProperties.getFormId());
            }
            //封装自定义流程定义信息
            FlowDefinitiontEntity flowDefinitiontEntity = new FlowDefinitiontEntity();
            Custom custom = childNodeList.getCustom();
            String title = childProperties.getTitle();
            String titleContent = childProperties.getTitleContent();
            flowDefinitiontEntity.setNodeId(custom.getNodeId());
            flowDefinitiontEntity.setNodeType(custom.getType());
            flowDefinitiontEntity.setNodeTitle(title);
            flowDefinitiontEntity.setNodeContent(titleContent);
            flowDefinitiontEntity.setNodeProperties(JsonUtilEx.getObjectToString(childProperties));
            flowDefinitiontEntity.setProcessDefinitionId(processDefinitionId);
            flowDefinitiontEntities.add(flowDefinitiontEntity);
        }
        flowDefinitionService.saveBatch(flowDefinitiontEntities);
        //信息事件配置
        entity.setSendConfigIds(JsonUtil.getObjectToString(sendIdList));
        //表单配置
        entity.setFormIds(JsonUtil.getObjectToString(formIdSet));
        return visibleList;
    }


    private BpmnModel assemBpmnModel(ChildNode childNode,BpmnModel bpmnModel,Process process) {
        //创建发起节点
        StartEvent startEvent = BpmnModelUtils.createStartEvent(process);
        Map<String,ChildNode>  conditionNodes =new HashMap<>();
        String endNodeId =assemProcess(startEvent.getId(),childNode,process,conditionNodes);
        EndEvent endEvent = BpmnModelUtils.createEndEvent();
        process.addFlowElement(connect(endNodeId, jnpf.engine.custom.constants.BasicActivitiConstants.endEventId));
        process.addFlowElement(endEvent);
        // new BpmnAutoLayout(bpmnModel).execute();
        BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
        byte[] bytes = bpmnXMLConverter.convertToXML(bpmnModel);
        return bpmnModel;
    }

    private String assemProcess(String startEventId,ChildNode childNode,Process process,Map<String,ChildNode>  conditionNodesList) {
        String type = childNode.getType();
        String nodeId = childNode.getNodeId();
        String currentNodeId="";
        if(FlowNodeTypeEnum.START.getType().equals(type)){
            UserTask userTask= new UserTask();
            userTask.setId(nodeId);
            String sequenceFlowId = childNode.getSequenceFlowId();
            SequenceFlow sequenceFlow = new SequenceFlow();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                sequenceFlow.setId(sequenceFlowId);
            }
            else{
                sequenceFlow.setId("se"+ IdWorker.getId());
            }
            sequenceFlow.setSourceRef(startEventId);
            sequenceFlow.setTargetRef(userTask.getId());
            process.addFlowElement(sequenceFlow);
            currentNodeId=nodeId;

            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
            Properties properties = childNode.getProperties();
            userTask.setName(properties.getTitle());
            properties.setAssigneeType(FlowTaskOperatorEnum.InitiatorMe.getCode());
            FlowFormEntity formEntity = flowFormService.getById(properties.getFormId());
            properties.setFlowFormEntity(formEntity);
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            userTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            userTask.addAttribute(extensionAttribute);
            process.addFlowElement(userTask);
        }
        else if(FlowNodeTypeEnum.APPROVER.getType().equals(type)){
            UserTask userTask= new UserTask();
            userTask.setId(nodeId);

            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,userTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                    process.addFlowElement(connect(startEventId,userTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            userTask.setName(properties.getTitle());
            userTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());
            //设置审批方式
            BpmnModelUtils.setCounterSignInfo(userTask,properties);
            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
            if(org.apache.commons.lang3.StringUtils.isNotBlank(properties.getFormId())){
                FlowFormEntity formEntity = flowFormService.getById(properties.getFormId());
                properties.setFlowFormEntity(formEntity);
            }
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            userTask.addAttribute(extensionAttribute);
            process.addFlowElement(userTask);
        }
        else if(FlowNodeTypeEnum.CALL_ACTIVITY.getType().equals(type)){
            Properties properties = childNode.getProperties();
                CallActivity callActivity=new CallActivity();
                callActivity.setId(nodeId);

                String sequenceFlowId = childNode.getSequenceFlowId();
                if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                    ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                    process.addFlowElement(connect(startEventId,nodeId,sequenceFlowId,conditionNode));
                }
                else{
                    process.addFlowElement(connect(startEventId,nodeId));
                }
                currentNodeId=nodeId;


                //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
                String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
                callActivity.setName(properties.getTitle());

                callActivity.setDocumentation(childNode.getContent()+ BasicActivitiConstants.taskDescriptionSeparator+temp+ BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());
                BpmnModelUtils.setCallActivityCounterSignInfo(callActivity,properties);
                String templateJsonId = childNode.getProperties().getFlowId();
                FlowTemplateJsonEntity flowTemplateJsonEntity = flowTemplateJsonService.getById(templateJsonId);
                callActivity.setCalledElement(activitiPrefix+flowTemplateJsonEntity.getGroupId());
                callActivity.setCalledElementType(CALLED_ELEMENT_TYPE_KEY);
                callActivity.setInheritBusinessKey(false);
                //
                FlowableListener flowableListener = new FlowableListener();
                flowableListener.setEvent(ExecutionListener.EVENTNAME_START);
                flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
                flowableListener.setImplementation("${callActivityStartedListener}");

                List<FlowableListener> flowableListenerList=new ArrayList<>();
                flowableListenerList.add(flowableListener);
                callActivity.setExecutionListeners(flowableListenerList);
//            List<FlowAssignModel> assignList = properties.getAssignList();
//            List<String> parentFields=new ArrayList<>();
//            List<String> subFields=new ArrayList<>();
//            List<IOParameter> ioParameterList=new ArrayList<>();
//            for (FlowAssignModel flowAssignModel : assignList) {
//                IOParameter ioParameter=new IOParameter();
//                ioParameter.setSource(flowAssignModel.getParentField());
//                ioParameter.setTarget(flowAssignModel.getChildField());
//                ioParameterList.add(ioParameter);
//            }
//            callActivity.setInParameters(ioParameterList);
                ExtensionAttribute extensionAttribute = new ExtensionAttribute();
                extensionAttribute.setNamespacePrefix(BasicActivitiConstants.exActivitiPrefix);
                extensionAttribute.setName(BasicActivitiConstants.extensionAttributeName);
                extensionAttribute.setNamespace(BasicActivitiConstants.exActivitiPrefixURL);
                String ex = JsonUtil.getObjectToString(properties);
                String str = JsonZipUtil.zipString(ex);
                extensionAttribute.setValue(str);
                callActivity.addAttribute(extensionAttribute);
                process.addFlowElement(callActivity);
        }
        else if(FlowNodeTypeEnum.TIMER.getType().equals(type)){
            ReceiveTask receiveTask= new ReceiveTask();
            receiveTask.setId(nodeId);

            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,receiveTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                process.addFlowElement(connect(startEventId,receiveTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            receiveTask.setName(properties.getTitle());
            receiveTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());
            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            receiveTask.addAttribute(extensionAttribute);
            process.addFlowElement(receiveTask);
        }
        else if(
                FlowNodeTypeEnum.COPY.getType().equals(type) || FlowNodeTypeEnum.DING.getType().equals(type)
                        ||FlowNodeTypeEnum.ZHAN.getType().equals(type) || FlowNodeTypeEnum.DX.getType().equals(type)
                        || FlowNodeTypeEnum.WX.getType().equals(type) || FlowNodeTypeEnum.HTTP_TASK.getType().equals(type)
                        || FlowNodeTypeEnum.SQL_TASK.getType().equals(type)||FlowNodeTypeEnum.MAIL.getType().equals(type) ||FlowNodeTypeEnum.MESSAGE.getType().equals(type) ||FlowNodeTypeEnum.SB.getType().equals(type)){
            ManualTask manualTask= new ManualTask();
            manualTask.setId(nodeId);

            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,manualTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                process.addFlowElement(connect(startEventId,manualTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            manualTask.setName(properties.getTitle());
            manualTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());
            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
//            if(org.apache.commons.lang3.StringUtils.isNotBlank(properties.getFormId())){
//                FlowFormEntity formEntity = flowFormService.getById(properties.getFormId());
//                properties.setFlowFormEntity(formEntity);
//            }

            properties.setNodeType(type);
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            manualTask.addAttribute(extensionAttribute);
            process.addFlowElement(manualTask);
        }

        else if(FlowNodeTypeEnum.SERVICE_TASK.getType().equals(type)){
            ServiceTask serviceTask= new ServiceTask();
            serviceTask.setId(nodeId);

            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,serviceTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                process.addFlowElement(connect(startEventId,serviceTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            serviceTask.setName(properties.getTitle());
            serviceTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());

            String serviceClassName = properties.getServiceClassName();

            serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
            //实现类
            serviceTask.setImplementation(serviceClassName);


            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
//            if(org.apache.commons.lang3.StringUtils.isNotBlank(properties.getFormId())){
//                FlowFormEntity formEntity = flowFormService.getById(properties.getFormId());
//                properties.setFlowFormEntity(formEntity);
//            }

            properties.setNodeType(type);
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            serviceTask.addAttribute(extensionAttribute);
            process.addFlowElement(serviceTask);
        }
        else if(FlowNodeTypeEnum.SHELL_TASK.getType().equals(type)){
//            if(activtes.equals("pro")){
//                throw  new WorkFlowException("出于安全起见,线上暂时不允许定义此类型节点!");
//            }
            ServiceTask serviceTask= new ServiceTask();
            serviceTask.setId(nodeId);
            serviceTask.setType("shell");
            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,serviceTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                process.addFlowElement(connect(startEventId,serviceTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            serviceTask.setName(properties.getTitle());
            serviceTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());

            String shellCommand = properties.getShellCommand();

            List<FieldExtension> fieldExtensionList=new ArrayList<>();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(shellCommand)){
                FieldExtension commandExtension=new FieldExtension();
                commandExtension.setFieldName("command");
                commandExtension.setStringValue(shellCommand);
                fieldExtensionList.add(commandExtension);
            }

            Boolean waitShellFlag = properties.getWaitShellFlag();
            if(waitShellFlag){
                FieldExtension commandExtension=new FieldExtension();
                commandExtension.setFieldName("wait");
                commandExtension.setStringValue(waitShellFlag+"");
                fieldExtensionList.add(commandExtension);
            }

            String shellDirectory = properties.getShellDirectory();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(shellDirectory)){
                FieldExtension commandExtension=new FieldExtension();
                commandExtension.setFieldName("directory");
                commandExtension.setStringValue(shellDirectory);
                fieldExtensionList.add(commandExtension);
            }
            serviceTask.setFieldExtensions(fieldExtensionList);


            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
//            if(org.apache.commons.lang3.StringUtils.isNotBlank(properties.getFormId())){
//                FlowFormEntity formEntity = flowFormService.getById(properties.getFormId());
//                properties.setFlowFormEntity(formEntity);
//            }

            properties.setNodeType(type);
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            serviceTask.addAttribute(extensionAttribute);
            process.addFlowElement(serviceTask);
        }
        else if(FlowNodeTypeEnum.SCRIPT_TASK.getType().equals(type)){
//            if(activtes.equals("pro")){
//                throw  new WorkFlowException("出于安全起见,线上暂时不允许定义此类型节点!");
//            }
            ScriptTask scriptTask= new ScriptTask();
            scriptTask.setId(nodeId);
            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,scriptTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                process.addFlowElement(connect(startEventId,scriptTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            scriptTask.setName(properties.getTitle());
            scriptTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());

            Integer scriptFormat = properties.getScriptFormat();
            String scriptContent = properties.getScriptContent();
            scriptTask.setScriptFormat(FlowScriptTypeEnum.getMessageByIndex(scriptFormat));

            if(scriptFormat==1){
                boolean b = grammarCheck(scriptContent);
                if(!b){
                    throw  new WorkFlowException("编写的Groovy脚本有问题,请重试");
                }
            }
            scriptTask.setScript(scriptContent);


            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
//            if(org.apache.commons.lang3.StringUtils.isNotBlank(properties.getFormId())){
//                FlowFormEntity formEntity = flowFormService.getById(properties.getFormId());
//                properties.setFlowFormEntity(formEntity);
//            }

            properties.setNodeType(type);
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            scriptTask.addAttribute(extensionAttribute);
            process.addFlowElement(scriptTask);
        }
        else if(FlowNodeTypeEnum.JUMP_TASK.getType().equals(type)){
            ManualTask serviceTask= new ManualTask();
            serviceTask.setId(nodeId);
            String sequenceFlowId = childNode.getSequenceFlowId();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                ChildNode conditionNode = conditionNodesList.get(sequenceFlowId);
                process.addFlowElement(connect(startEventId,serviceTask.getId(),sequenceFlowId,conditionNode));
            }
            else{
                process.addFlowElement(connect(startEventId,serviceTask.getId()));
            }
            currentNodeId=nodeId;
            Properties properties = childNode.getProperties();
            //content 和 description  都放到这个字段中 逗号隔开就行  也可以存储到扩展属性中 但是没啥必要
            String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription())==true?"描述":properties.getDescription();
            serviceTask.setName(properties.getTitle());
            serviceTask.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());

            FlowableListener flowableListener = new FlowableListener();
            flowableListener.setEvent(ExecutionListener.EVENTNAME_START);
            flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
            flowableListener.setImplementation("${jumpTaskListener}");

            List<FlowableListener> flowableListenerList=new ArrayList<>();
            flowableListenerList.add(flowableListener);
            serviceTask.setExecutionListeners(flowableListenerList);


            ExtensionAttribute extensionAttribute = new ExtensionAttribute();
            extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
            extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
            extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);


            properties.setNodeType(type);
            String ex = JsonUtil.getObjectToString(properties);
            String str = JsonZipUtil.zipString(ex);
            extensionAttribute.setValue(str);
            serviceTask.addAttribute(extensionAttribute);
            process.addFlowElement(serviceTask);
        }
        String endNodeId=eachConditionNode(currentNodeId,childNode,process,null,conditionNodesList);
        return endNodeId;

    }

    public static boolean grammarCheck(String exp) {
        try {
            new GroovyShell().parse(exp);
            return true;
        } catch(MultipleCompilationErrorsException cfe) {
            return false;
        }
    }


    private String  eachConditionNode(String id, ChildNode childNode, Process process,String sequenceFlowId,Map<String,ChildNode> conditionNodeList) {
        String tempSequenceFlowId=sequenceFlowId;
        String currentType = childNode.getType();
        List<ChildNode> conditionNodes = childNode.getConditionNodes();
        String conditionType = childNode.getConditionType();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(conditionType) &&CollectionUtil.isEmpty(conditionNodes)){
            childNode.setConditionType(null);
        }
        if(org.apache.commons.lang3.StringUtils.isBlank(conditionType) && CollectionUtil.isNotEmpty(conditionNodes)){
            ChildNode tempConditionNode = conditionNodes.get(0);
            String type = tempConditionNode.getType();
            Boolean isBranchFlow = tempConditionNode.getIsBranchFlow();
            Boolean isInterflow = tempConditionNode.getIsInterflow();
            Boolean flag=false;
            if("condition".equals(type)){
                childNode.setConditionType("condition");
                flag=true;
            }
            if(!flag){
                if(isInterflow!=null &&isInterflow){
                    childNode.setConditionType("interFlow");
                }

            }
            if(!flag){
                if(isBranchFlow!=null && isBranchFlow){
                    childNode.setConditionType("branchFlow");
                }
            }
        }
        Boolean childNodeIsInterflow = childNode.getIsInterflow();
        Boolean childNodeIsBranchFlow = childNode.getIsBranchFlow();
        conditionType = childNode.getConditionType();
        if(org.apache.commons.lang3.StringUtils.isNotBlank(conditionType)){
            if("condition".equals(conditionType)){
//                if("condition".equals(currentType)){
                Boolean plusFlag=false;
                for (ChildNode conditionNode : conditionNodes) {
                    Properties properties = conditionNode.getProperties();
                    if(Boolean.TRUE.equals(properties.getPlusFlag())){
                        plusFlag=true;
                        break;
                    }
                }
                Gateway exclusiveGateway=null;
                String exclusiveGatewayId=null;

                Gateway endExclusiveGateway = null;
                String endExclusiveGatewayId = "";
                if(plusFlag){
                    exclusiveGateway=new InclusiveGateway();
                    exclusiveGatewayId = id("inclusiveGateway");
                    endExclusiveGatewayId=exclusiveGatewayId+"_end";
                    exclusiveGateway.setId(exclusiveGatewayId);
                    endExclusiveGateway= new InclusiveGateway();
                    endExclusiveGateway.setId(endExclusiveGatewayId);
                }
                else{
                    exclusiveGateway=new ExclusiveGateway();
                    exclusiveGatewayId = id("exclusiveGateway");
                    endExclusiveGatewayId=exclusiveGatewayId+"_end";
                    exclusiveGateway.setId(exclusiveGatewayId);
                    endExclusiveGateway= new ExclusiveGateway();
                    endExclusiveGateway.setId(endExclusiveGatewayId);
                }
                process.addFlowElement(exclusiveGateway);
                process.addFlowElement(endExclusiveGateway);
                SequenceFlow connect=null;
                if(org.apache.commons.lang3.StringUtils.isNotBlank(sequenceFlowId)){
                    connect= connect(id, exclusiveGatewayId,sequenceFlowId,childNode);
                    sequenceFlowId=null;
                }
                else{
                    connect= connect(id, exclusiveGatewayId);
                }

                process.addFlowElement(connect);





                if(CollectionUtil.isNotEmpty(conditionNodes)){
                    List<String> eachEndNodeIds=new ArrayList<>();
                    for (ChildNode conditionNode : conditionNodes) {
                        deepChildNode(conditionNode,exclusiveGatewayId);
                    }
                    for (ChildNode conditionNode : conditionNodes) {
                        conditionNodeList.put(conditionNode.getNodeId(),conditionNode);
                        Properties properties = conditionNode.getProperties();
                        Boolean isDefault = properties.getIsDefault();
                        if(isDefault){
                            exclusiveGateway.setDefaultFlow(conditionNode.getNodeId());
                        }
//                        properties.setGatewayId(exclusiveGatewayId);
//                        conditionNode.setGatewayId(exclusiveGatewayId);
                        String nodeId = conditionNode.getNodeId();
                        String eachEndNodeId = eachConditionNode(exclusiveGatewayId, conditionNode, process, nodeId,conditionNodeList);
                        eachEndNodeId=eachEndNodeId+"@#@"+conditionNode.getNodeId();
                        eachEndNodeIds.add(eachEndNodeId);
                    }

                    for (String eachEndNodeId : eachEndNodeIds) {
                        String[] split = eachEndNodeId.split("@#@");
                        String fromNodeId=split[0];
                        String sequenceFlowUId=split[1];
                        ChildNode tempNode = conditionNodeList.get(sequenceFlowUId);
                        if(tempNode!=null){
                            String swerveNode = tempNode.getProperties().getSwerveNode();
                            if(StringUtils.isNotBlank(swerveNode)){
                                if(fromNodeId.startsWith("exclusiveGateway")|| fromNodeId.startsWith("inclusiveGateway")){
                                    if(fromNodeId.endsWith("_end")){  //end网关和end链接的时候
                                        process.addFlowElement(connect(split[0],endExclusiveGatewayId));
                                    }
                                    else{
                                        //创建一个servcieTask  网关和
                                        String swerveServiceTaskId = BpmnModelUtils.createSwerveServiceTask(split[0], process,conditionNodeList,split[1]);
                                        process.addFlowElement(connect(split[0],swerveServiceTaskId,sequenceFlowUId,tempNode));
                                        process.addFlowElement(connect(swerveServiceTaskId,endExclusiveGatewayId));
                                    }

                                }
                                else{
                                    process.addFlowElement(connect(split[0],endExclusiveGatewayId));
                                }
                            }
                            else{
                                String randomUId = id("sequenceFlow");
                                if(fromNodeId.startsWith("exclusiveGateway")|| fromNodeId.startsWith("inclusiveGateway")){
                                    if(fromNodeId.endsWith("_end")){  //end网关和end链接的时候
                                        process.addFlowElement(connect(split[0],endExclusiveGatewayId));
                                    }
                                    else{
                                        process.addFlowElement(connect(split[0],endExclusiveGatewayId,sequenceFlowUId,tempNode));
                                    }

                                }
                                else{
                                    process.addFlowElement(connect(split[0],endExclusiveGatewayId));
                                }
                            }

                        }
                        else{
                            process.addFlowElement(connect(split[0],endExclusiveGatewayId));
                        }
//                            if(StrUtil.endWith(fromNodeId,"_end")){
//                                process.addFlowElement(connect(split[0],endExclusiveGatewayId));
//                            }
//                            else{
//                                process.addFlowElement(connect(split[0],endExclusiveGatewayId,split[1]));
//                            }

                    }
                }


                //递归子节点
                ChildNode childNodeTemp = childNode.getChildNode();
                if(childNodeTemp==null){
                    return endExclusiveGatewayId;
                }
                else{
                    String endNodeId = assemProcess(endExclusiveGatewayId, childNodeTemp, process,conditionNodeList);
                    return endNodeId;
                }
//                }


            }
            else if("interflow".equals(conditionType)){
                ParallelGateway exclusiveGateway = new ParallelGateway();
                String parallelGatewayId = id("parallelGateway");
                exclusiveGateway.setId(parallelGatewayId);
                process.addFlowElement(exclusiveGateway);
//                SequenceFlow connect=connect(id, parallelGatewayId);
                SequenceFlow connect=null;
                if(org.apache.commons.lang3.StringUtils.isNotBlank(tempSequenceFlowId)){
                    ChildNode conditionNodeTemp = conditionNodeList.get(tempSequenceFlowId);
                    connect= connect(id, parallelGatewayId,sequenceFlowId,conditionNodeTemp);
                }
                else{
                    connect= connect(id, parallelGatewayId);
                }
                process.addFlowElement(connect);
                ParallelGateway exclusiveGatewayEndId = new ParallelGateway();
                String endparallelGatewayId = parallelGatewayId+"_end";
                exclusiveGatewayEndId.setId(endparallelGatewayId);
                process.addFlowElement(exclusiveGatewayEndId);



                if(CollectionUtil.isNotEmpty(conditionNodes)){
                    List<String> eachEndNodeIds=new ArrayList<>();
                    for (ChildNode conditionNode : conditionNodes) {
                        deepChildNode(conditionNode,parallelGatewayId);
                    }
                    for (ChildNode conditionNode : conditionNodes) {
//                        conditionNode.setGatewayId(parallelGatewayId);
                        Properties properties = conditionNode.getProperties();
//                        properties.setGatewayId(parallelGatewayId);
                        String branchFlowId = conditionNode.getNodeId();
                        properties.setBranchFlowId(branchFlowId);
//                        String nodeId = conditionNode.getNodeId();
                        String endNodeId = assemProcess(parallelGatewayId, conditionNode, process,conditionNodeList);
//                        String eachEndNodeId = eachConditionNode(parallelGatewayId, conditionNode, process, null,conditionNodeList);
                        endNodeId=endNodeId+"@#@"+conditionNode.getNodeId();
                        eachEndNodeIds.add(endNodeId);
                    }

                    for (String eachEndNodeId : eachEndNodeIds) {
                        String[] split = eachEndNodeId.split("@#@");
                        process.addFlowElement(connect(split[0],endparallelGatewayId));
                    }
                }


                //递归子节点
                ChildNode childNodeTemp = childNode.getChildNode();
                if(childNodeTemp==null){
                    return endparallelGatewayId;
                }
                else{
                    String endNodeId = assemProcess(endparallelGatewayId, childNodeTemp, process,conditionNodeList);
                    return endNodeId;
                }



            }
            else{
                return "";
            }
        }

        else{
            Boolean isBranchFlow = childNode.getIsBranchFlow();
            Boolean isInterflow = childNode.getIsInterflow();
            String type = childNode.getType();
            if("condition".equals(type)){
                ChildNode childNodeTemp = childNode.getChildNode();
                if(childNodeTemp==null){
                    //是
                    if("condition".equals(type) || isBranchFlow ||isInterflow){
                        return childNode.getGatewayId();
                    }
                    else{
                        return id;
                    }

                }
                else{
                    if(org.apache.commons.lang3.StringUtils.isNotBlank(tempSequenceFlowId)){
                        childNodeTemp.setSequenceFlowId(tempSequenceFlowId);
                    }
                    String endNodeId = assemProcess(id, childNodeTemp, process,conditionNodeList);
                    return endNodeId;
                }
            }
            else if(Boolean.TRUE.equals(isBranchFlow)){
                FlowElement flowElement = process.getFlowElement(childNode.getNodeId());
                if(flowElement==null){
                    String endNodeId = assemProcess(id, childNode, process,conditionNodeList);
                    return endNodeId;
                }
                ChildNode childNodeTemp = childNode.getChildNode();
                if(childNodeTemp==null){
                    return id;
                }
                else{
                    String branchFlowId = childNode.getProperties().getBranchFlowId();
                    if(org.apache.commons.lang3.StringUtils.isNotBlank(branchFlowId)){
                        childNodeTemp.getProperties().setBranchFlowId(branchFlowId);
                    }
                    String endNodeId = assemProcess(id, childNodeTemp, process,conditionNodeList);
                    return endNodeId;
                }
            }
            else if(Boolean.TRUE.equals(isInterflow)){
                FlowElement flowElement = process.getFlowElement(childNode.getNodeId());
                if(flowElement==null){
                    String endNodeId = assemProcess(id, childNode, process,conditionNodeList);
                    return endNodeId;
                }
                ChildNode childNodeTemp = childNode.getChildNode();
                if(childNodeTemp==null){
                    return id;
                }
                else{
                    String branchFlowId = childNode.getProperties().getBranchFlowId();
                    if(org.apache.commons.lang3.StringUtils.isNotBlank(branchFlowId)){
                        childNodeTemp.getProperties().setBranchFlowId(branchFlowId);
                    }
                    String endNodeId = assemProcess(id, childNodeTemp, process,conditionNodeList);
                    return endNodeId;
                }
            }
            else{
                FlowElement flowElement = process.getFlowElement(childNode.getNodeId());
                if(flowElement==null){
                    String endNodeId = assemProcess(id, childNode, process,conditionNodeList);
                    return endNodeId;
                }
                ChildNode childNodeTemp = childNode.getChildNode();
                if(childNodeTemp==null){
                    return id;
                }
                else{
                    String branchFlowId = childNode.getProperties().getBranchFlowId();
                    if(org.apache.commons.lang3.StringUtils.isNotBlank(branchFlowId)){
                        childNodeTemp.getProperties().setBranchFlowId(branchFlowId);
                    }
                    String endNodeId = assemProcess(id, childNodeTemp, process,conditionNodeList);
                    return endNodeId;
                }
            }

        }

    }

    private void deepBranchChildNode(ChildNode conditionNode,  String exclusiveGatewayId,String branchFirstNodeId) {
        if(conditionNode!=null){
            conditionNode.setGatewayId(exclusiveGatewayId);
            conditionNode.getProperties().setGatewayId(exclusiveGatewayId);
            ChildNode childNode1 = conditionNode.getChildNode();
            if(childNode1!=null){
                childNode1.getProperties().setBranchFlowId(branchFirstNodeId);
                childNode1.setGatewayId(exclusiveGatewayId);
                childNode1.getProperties().setGatewayId(exclusiveGatewayId);
                deepChildNode(childNode1.getChildNode(),branchFirstNodeId);
            }
        }
    }

    private void deepChildNode(ChildNode conditionNode, String exclusiveGatewayId) {
        if(conditionNode!=null){
            conditionNode.setGatewayId(exclusiveGatewayId);
            conditionNode.getProperties().setGatewayId(exclusiveGatewayId);
            ChildNode childNode1 = conditionNode.getChildNode();
            if(childNode1!=null){
                childNode1.setGatewayId(exclusiveGatewayId);
                childNode1.getProperties().setGatewayId(exclusiveGatewayId);
                deepChildNode(childNode1.getChildNode(),exclusiveGatewayId);
            }
        }
    }

    protected static SequenceFlow connect(String from, String to) {
        SequenceFlow flow = new SequenceFlow();
        flow.setId(id("sequenceFlow"));
        flow.setSourceRef(from);
        flow.setTargetRef(to);

        return flow;
    }


    protected static SequenceFlow connectBranchFlow(String from, String to) {
        SequenceFlow flow = new SequenceFlow();
        flow.setId(id("sequenceFlow"));
        flow.setSourceRef(from);
        flow.setTargetRef(to);
        flow.setConditionExpression(SEQUENCE_FLOW_WITH_CONDITION_EXPRESSION);
        return flow;
    }


    protected static SequenceFlow connect(String from, String to,String sequenceFlowId,ChildNode childNode) {
        SequenceFlow flow = new SequenceFlow();
        flow.setId(sequenceFlowId);
        flow.setSourceRef(from);
        flow.setTargetRef(to);
        flow.setName(childNode.getContent());
        ExtensionAttribute extensionAttribute = new ExtensionAttribute();
        extensionAttribute.setNamespacePrefix(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefix);
        extensionAttribute.setName(jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName);
        extensionAttribute.setNamespace(jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL);
        Properties properties = childNode.getProperties();
        if(null==properties.getModeFlag()){
            if(Boolean.TRUE.equals(properties.getIsDefault())){}
            else{
                flow.setConditionExpression(SEQUENCE_FLOW_WITH_CONDITION_EXPRESSION);
            }

        }
        else{
            List<ProperCond> conditions = properties.getConditions();
            if(CollUtil.isEmpty(conditions)){
                if(properties.getModeFlag().equals(2)){
                    String conditionExpStr = EvalUtils.assemConditionExpStr(to, properties, conditions,flow.getId());
                    flow.setConditionExpression(conditionExpStr);
                }
            }
            else{
                String conditionExpStr = EvalUtils.assemConditionExpStr(to, properties, conditions,flow.getId());
                flow.setConditionExpression(conditionExpStr);
            }
        }
        String temp= org.apache.commons.lang3.StringUtils.isBlank(properties.getDescription()) ?"描述":properties.getDescription();
        flow.setDocumentation(childNode.getContent()+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+temp+ jnpf.engine.custom.constants.BasicActivitiConstants.taskDescriptionSeparator+properties.getTitle());
        String ex = JsonUtil.getObjectToString(properties);
        String compress = JsonZipUtil.zipString(ex);
        extensionAttribute.setValue(new String(compress));
        flow.addAttribute(extensionAttribute);
        return flow;
    }


    private static String id(String prefix) {
        return prefix + "-" + UUID.randomUUID().toString().replace("-", "").toLowerCase();
    }


    @Override
    public List<FlowTemplateEntity> getListByFlowIds(FlowPagination pagination, List<String> listAll, Boolean isAll, Boolean isPage, String userId) {
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getEnabledMark, 1);
        List<String> listIn = new ArrayList<>();
        List<String> listVisible = null;
        if (StringUtil.isNotEmpty(userId)) {//当用户不为空的时候【判断该用户的权限
            UserEntity userInfo = serviceUtil.getUserInfo(userId);
            boolean visibleType = "1".equals(userInfo.getIsAdministrator());
            if (!visibleType) {
                List<String> id = flowEngineVisibleService.getVisibleFlowList(userInfo.getId()).stream().map(FlowEngineVisibleEntity::getFlowId).collect(Collectors.toList());
                //可见列表
                listVisible = flowTemplateJsonService.getListAll(id).stream().map(FlowTemplateJsonEntity::getTemplateId).collect(Collectors.toList());
            }
            if (CollectionUtil.isNotEmpty(listVisible) && CollectionUtil.isNotEmpty(listAll)) {
                for (String str : listAll) {
                    if (listVisible.contains(str)) {
                        listIn.add(str);
                    }
                }
            } else if (isAll) {
                listIn = listVisible;
            }
        } else {//不判断用户权限
            listIn = listAll;
        }
        if (CollectionUtil.isEmpty(listIn) && !isAll) {
            return new ArrayList<>();
        }
        if (CollectionUtil.isNotEmpty(listIn)) {
            queryWrapper.lambda().in(FlowTemplateEntity::getId, listIn);
        }
        if (ObjectUtil.isNotEmpty(pagination.getKeyword())) {
            flag = true;
            queryWrapper.lambda().like(FlowTemplateEntity::getFullName, pagination.getKeyword());
        }
        if (ObjectUtil.isNotEmpty(pagination.getCategory())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTemplateEntity::getCategory, pagination.getCategory());
        }
        if (ObjectUtil.isNotEmpty(pagination.getFlowType())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTemplateEntity::getType, pagination.getFlowType());
        }
        queryWrapper.lambda().orderByAsc(FlowTemplateEntity::getSortCode).orderByDesc(FlowTemplateEntity::getCreatorTime);
        if (flag) {
            queryWrapper.lambda().orderByDesc(FlowTemplateEntity::getLastModifyTime);
        }
        queryWrapper.lambda().select(
                FlowTemplateEntity::getId, FlowTemplateEntity::getEnCode,
                FlowTemplateEntity::getFullName,
                FlowTemplateEntity::getType, FlowTemplateEntity::getIcon,
                FlowTemplateEntity::getCategory, FlowTemplateEntity::getIconBackground,
                FlowTemplateEntity::getCreatorUserId, FlowTemplateEntity::getSortCode,
                FlowTemplateEntity::getEnabledMark, FlowTemplateEntity::getCreatorTime
        );
        if (isPage) {
            Page<FlowTemplateEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
            IPage<FlowTemplateEntity> userPage = this.page(page, queryWrapper);
            return pagination.setData(userPage.getRecords(), page.getTotal());
        } else {
            return list(queryWrapper);
        }

    }

    @Override
    public void saveLogicFlowAndForm(String id) {
        FlowTemplateEntity flowEnt = this.setIgnoreLogicDelete().getById(id);
        if (flowEnt != null) {
            flowEnt.setDeleteMark(null);
            this.setIgnoreLogicDelete().updateById(flowEnt);
            QueryWrapper<FlowTemplateJsonEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(FlowTemplateJsonEntity::getTemplateId, id);
            List<FlowTemplateJsonEntity> list = flowTemplateJsonService.setIgnoreLogicDelete().list(queryWrapper);
            list.forEach(t -> t.setDeleteMark(null));
            flowTemplateJsonService.setIgnoreLogicDelete().updateBatchById(list);
        }
        this.clearIgnoreLogicDelete();
    }

    private FlowTemplateEntity Import(FlowTemplateEntity templateEntity, String type, List<String> errList) {
        FlowTemplateEntity entity = JsonUtil.getJsonToBean(templateEntity, FlowTemplateEntity.class);
        boolean skip = Objects.equals("0", type);
        int num = 0;
        QueryWrapper<FlowTemplateEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getId, entity.getId());
        if (this.count(queryWrapper) > 0) {
            num++;
            if (skip) {
                errList.add("ID");
            }
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getEnCode, entity.getEnCode());
        if (this.count(queryWrapper) > 0) {
            num++;
            if (skip) {
                errList.add("编码");
            }
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateEntity::getFullName, entity.getFullName());
        if (this.count(queryWrapper) > 0) {
            num++;
            if (skip) {
                errList.add("名称");
            }
        }
        if (num > 0 && !skip) {
            String copyNum = UUID.randomUUID().toString().substring(0, 5);
            entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            entity.setEnCode(entity.getEnCode() + copyNum);
        }
        entity.setId(RandomUtil.uuId());
        return entity;
    }

    private FlowTemplateJsonEntity Import(FlowTemplateJsonEntity templateEntity, String type, List<String> idList, List<String> nameList) {
        FlowTemplateJsonEntity entity = JsonUtil.getJsonToBean(templateEntity, FlowTemplateJsonEntity.class);
        boolean skip = Objects.equals("0", type);
        QueryWrapper<FlowTemplateJsonEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateJsonEntity::getId, entity.getId());
        if (flowTemplateJsonService.count(queryWrapper) > 0) {
            if (skip) {
                idList.add(entity.getId());
            }
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTemplateJsonEntity::getFullName, entity.getFullName());
        queryWrapper.lambda().eq(FlowTemplateJsonEntity::getTemplateId, entity.getId());
        if (flowTemplateJsonService.count(queryWrapper) > 0) {
            if (skip) {
                nameList.add(entity.getFullName());
            }
        }
        entity.setId(RandomUtil.uuId());
        return entity;
    }
}
